#include "stdafx.h"
#include "ObjContainer.h"
#include "Obj.h"
#include "core/Collision.hpp"
#include "terrain/Terrain.h"
#include "graphics/ParticleSystem.h"

ObjContainer* ObjContainer::instance = nullptr;

ObjContainer* ObjContainer::getInstance() {
	if(!instance)
		instance = new ObjContainer();
	return instance;
}

ObjContainer::ObjContainer() {

}

void ObjContainer::draw(const glm::mat4 & viewMatrix, bool picking) {

	for ( auto it = objList.begin(); it != objList.end(); it++) {
		(*it)->draw(picking); // put rendering info in BoxPrimitive static list to be rendered
	} 
	Game::getInstance()->boxRenderer->drawBatched(viewMatrix); // draw batched 

	Terrain::getInstance()->render(viewMatrix, picking);
}

void ObjContainer::addObj(Obj* obj) {
	addsScheduled.push_back(obj);
}

Obj* ObjContainer::colorPick(FBO_RB pickingFBO, const glm::dvec2& mousePos) {
	
	glm::vec4 pixel = pickingFBO.sample(glm::dvec2(mousePos.x, Game::windowDim.y - mousePos.y));
	return getObjFromColor(pixel);
}

Obj* ObjContainer::getObjFromColor(const glm::vec4& color)
{
	if ( color.x > 1e-6 || color.y > 1e-6 ) // we have clicked the terrain 
		return nullptr;

	for ( auto it = objList.begin(); it != objList.end(); ++it)
	{
		if ( (*it)->hasPickColor(static_cast<unsigned short>(color.z*0xffff+0.5f)) )
			return (*it);
	}
	return nullptr;
}

void ObjContainer::update(float dt) {
	Terrain* terrain = Terrain::getInstance();
	ParticleSystem* particleSystem = Game::getInstance()->particleSystem;

	for ( auto it = objList.begin(); it != objList.end(); it++) {
		(*it)->update(dt);
	}

	// add new objs
	if (!addsScheduled.empty()) {
		objList.insert(objList.end(), addsScheduled.begin(), addsScheduled.end());
		addsScheduled.clear();
	}

	// remove dead objs 
	for	( auto it = objList.begin(); it != objList.end(); ) {
		if ((*it)->toBeDeleted) {
			delete (*it);
			it = objList.erase(it);
		} else { 
			it++;
		}
	}
}
